package org.xiyu.yee.beacon_anti_phantom.beacon;

import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BeaconBlockEntity;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import org.xiyu.yee.beacon_anti_phantom.config.BeaconConfig;

import java.util.*;

public class BeaconManager {
    private static BeaconManager instance;
    private final Map<BlockPos, Integer> activeBeacons = new HashMap<>();
    private final Map<BlockPos, Integer> beaconRadiusCache = new HashMap<>();
    
    private BeaconManager() {}
    
    public static BeaconManager getInstance() {
        if (instance == null) {
            instance = new BeaconManager();
        }
        return instance;
    }
    
    /**
     * 更新服务器世界中的所有信标
     */
    public void updateBeacons(ServerLevel level) {
        activeBeacons.clear();
        beaconRadiusCache.clear();
        
        // 使用一个更安全的方法来获取所有信标
        // 遍历玩家周围的已加载区块
        level.players().forEach(player -> {
            int chunkRange = 8; // 检查玩家周围8个区块范围
            int playerChunkX = player.chunkPosition().x;
            int playerChunkZ = player.chunkPosition().z;
            
            for (int x = playerChunkX - chunkRange; x <= playerChunkX + chunkRange; x++) {
                for (int z = playerChunkZ - chunkRange; z <= playerChunkZ + chunkRange; z++) {
                    if (level.hasChunk(x, z)) {
                        net.minecraft.world.level.chunk.LevelChunk chunk = level.getChunk(x, z);
                        chunk.getBlockEntities().forEach((pos, blockEntity) -> {
                            if (blockEntity instanceof BeaconBlockEntity beacon) {
                                if (level.getBlockState(pos).is(Blocks.BEACON)) {
                                    int beaconLevel = getBeaconLevel(level, pos);
                                    if (beaconLevel > 0) {
                                        activeBeacons.put(pos, beaconLevel);
                                        int radius = BeaconConfig.getInstance().getRadius(beaconLevel);
                                        beaconRadiusCache.put(pos, radius);
                                    }
                                }
                            }
                        });
                    }
                }
            }
        });
    }
    
    /**
     * 获取信标等级
     */
    private int getBeaconLevel(ServerLevel level, BlockPos beaconPos) {
        int level1 = 0;
        
        // 检查信标底下的金字塔结构
        for (int y = 1; y <= 4; y++) {
            int size = y * 2 + 1;
            int validBlocks = 0;
            int totalBlocks = size * size;
            
            for (int x = -y; x <= y; x++) {
                for (int z = -y; z <= y; z++) {
                    BlockPos checkPos = beaconPos.offset(x, -y, z);
                    if (isValidBeaconBase(level.getBlockState(checkPos).getBlock())) {
                        validBlocks++;
                    }
                }
            }
            
            if (validBlocks == totalBlocks) {
                level1 = y;
            } else {
                break;
            }
        }
        
        return level1;
    }
    
    /**
     * 检查方块是否可以作为信标底座
     */
    private boolean isValidBeaconBase(net.minecraft.world.level.block.Block block) {
        return block == Blocks.IRON_BLOCK ||
               block == Blocks.GOLD_BLOCK ||
               block == Blocks.DIAMOND_BLOCK ||
               block == Blocks.EMERALD_BLOCK ||
               block == Blocks.NETHERITE_BLOCK;
    }
    
    /**
     * 检查位置是否在任何信标的保护范围内
     */
    public boolean isInBeaconRange(BlockPos pos) {
        AABB aabb = new AABB(new Vec3(0,0,0),new Vec3(5,5,5));
        aabb.contains(pos.getCenter());

        for (Map.Entry<BlockPos, Integer> entry : beaconRadiusCache.entrySet()) {
            BlockPos beaconPos = entry.getKey();
            int radius = entry.getValue();
            
            double distance = Math.sqrt(Math.pow(pos.getX() - beaconPos.getX(), 2) + 
                                      Math.pow(pos.getZ() - beaconPos.getZ(), 2));
            
            if (distance <= radius) {
                return true;
            }
        }
        return false;
    }
    
    /**
     * 获取所有激活的信标
     */
    public Map<BlockPos, Integer> getActiveBeacons() {
        return new HashMap<>(activeBeacons);
    }
    
    /**
     * 获取信标的保护半径
     */
    public int getBeaconRadius(BlockPos beaconPos) {
        return beaconRadiusCache.getOrDefault(beaconPos, 0);
    }
    
    /**
     * 检查是否有任何激活的信标
     */
    public boolean hasAnyBeacons() {
        return !activeBeacons.isEmpty();
    }
}
